/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package edu.uoc.tfc.exuoc.controladors;

import edu.uoc.tfc.exuoc.config.Config;
import edu.uoc.tfc.exuoc.model.Contenidor;
import edu.uoc.tfc.exuoc.model.Item;


import java.io.UnsupportedEncodingException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.hibernate.HibernateException;

import edu.uoc.tfc.exuoc.errors.BuitException;

import java.util.Iterator;
import edu.uoc.tfc.exuoc.utils.Eines;




/**
 * Classe que gestionarà la persistència mitjançant la classe
 * GestorBDD (genèrica)
 *
 * @author emoreno
 */
public class ContenidorsDAO {
    private GestorBDD gd=new GestorBDD();
    private GestorLogs  log=GestorLogs .getLogger(this.getClass().getName());

    protected ContenidorsDAO(){
    }

    public void tancarConnexio() throws HibernateException{
        try {
            gd.close();
        }catch(java.lang.NullPointerException e){
            this.log.info("Connexió ja tancada");
        }
        gd=null;
    }


    protected void evict(Object o ){
        gd.evict(o);
    }
    protected    void persist(Object o){
        gd.persist(o);
    }
   
    public Long afegirContenidor(Contenidor contenidor) throws HibernateException, BuitException{
        Long id=Config.valorNull;

        try {
            //gd.getSessio().beginTransaction();
            //gd.begin();
            id=gd.afegir(contenidor);
        }catch (HibernateException e){
            log.error("No s'ha pogut afegir el contenidor ({})  ",contenidor.getClass().getCanonicalName());
            throw e;
        }catch (BuitException e){
            log.error("No s'ha pogut afegir el contenidor ({})  ",contenidor.getClass().getCanonicalName());
            throw e;
        }
        return id;
    }

    public void eliminarContenidor(Contenidor contenidor) throws HibernateException, BuitException{
        try {
            //gd.getSessio().beginTransaction();
           // gd.begin();
            gd.eliminar(contenidor);
        }catch (HibernateException e){
            log.error("No s'ha pogut eliminar el contenidor id:  "+contenidor.getId()+". {}",e.getMessage());
            throw e;
        }catch (BuitException e){
            log.error("algun valor és buit el contenidor di:  "+contenidor.getId()+". {}",e.getMessage());
            throw e;
        }
    }
    

    public void modificarContenidor(Contenidor contenidor) throws HibernateException, BuitException{
            try {
                //this.log.error("ContenidorsDAO: "+contenidor.toString());
                //gd.persist(contenidor);
                this.log.info("ContenidorsDAO: "+contenidor.toString()+",ver="+contenidor.getVersionNum());
                this.log.info("num Items: "+contenidor.getItems().size());
                
                //18 20:53 gd.begin();
                if (contenidor.getId()!=Config.valorNull &&
                        contenidor.getId()!=null)
                {
                    gd.modificar(contenidor);
                    /*Session sessio =GestorBDD.getSessio();
                    Transaction tran=sessio.beginTransaction();
                    tran.begin();
                    sessio.update(contenidor);
                    tran.commit();
                    Eines.escriu("S'ha guardat ? "+tran.wasCommitted());
                    
                    sessio.close();*/
                }
                else throw new BuitException("Id del contenidor null, nom: "+ contenidor.getNom());


            }catch (HibernateException e){
                log.error("Hibernate ha donat un error pel contenidor :{})"+contenidor.getNom(),e.getMessage());
                throw e;
            }catch (BuitException e){
                log.error("Error en la modificacio del contenidor :{})"+contenidor.getNom(),e.getMessage());
                throw e;
            }catch(Exception e){
                this.log.error("-----------------: ",e.getLocalizedMessage());
            }
            finally{
               // gd.close();
            }

    }
    public Contenidor consultaContenidor(Long id) throws HibernateException, BuitException {
        Contenidor co=null;
        try{
           // gd.begin();
            co=(Contenidor)gd.llegir(Contenidor.class, id);
          //  gd.evict(co);
        }catch(HibernateException e){
            log.error("No s'ha pogut obentir el contenidor :{}  ",String.valueOf(id));
            throw e;

        }catch (BuitException e){
            log.error("No s'ha pogut obtenir el contenidor ({})  ",String.valueOf(id));
            throw e;
        }
        return co;
    }

    public Contenidor consultaContenidor(String nom) throws HibernateException, BuitException {
        Contenidor co=null;
        try{
           // gd.begin();
            co=(Contenidor)gd.llegir(Contenidor.class, "nom", nom);
           // gd.evict(co);

        }catch(HibernateException e){
            log.error("No s'ha pogut obentir el contenidor :{}  ",nom);
            throw e;

        }catch (BuitException e){
            log.error("No s'ha pogut obtenir el contenidor ({})  ",nom);
            throw e;
        }catch (UnsupportedEncodingException e){
            log.error("No s'ha pogut obtenir el contenidor ({})  ",nom);
            throw new BuitException("Nom del contenidor incorrecte");
        }
        return co;
    }

    public Contenidor consultaContenidor(Class classe ,Long id)
            throws HibernateException, BuitException {
        Contenidor co=null;

        try{
            //gd.begin();
            co=(Contenidor)gd.llegir(classe, id);
            //gd.evict(co);
            
        }catch(HibernateException e){
            log.error("No s'ha pogut obentir el contenidor :{}  ",String.valueOf(id));
            //throw e;
        }catch (BuitException e){
            log.error("No s'ha pogut obtenir el contenidor ({})  ",String.valueOf(id));
            throw e;
        }
        return co;
    }
    
    public Iterator<Contenidor> llista()  throws HibernateException, BuitException{
        Iterator<Contenidor> llistat =null;
        try{
            //gd.begin();
            llistat=((Iterator<Contenidor>)gd.Llista(Contenidor.class).iterator());
        }catch (BuitException e){
            log.error("No s'ha pogut obtenir el llistat de contenidors.{} ",e.getLocalizedMessage());
            throw e;
        }catch(HibernateException e){
            log.error("llistat amb errors d'hibernate ({})  ",e.getLocalizedMessage());
            throw e;
        }
        finally{
           // gd.close();
        }
        return llistat;
    }
    
    public Iterator<Contenidor> llista(int ini, int fi)  throws HibernateException, BuitException{
        Iterator llistat =null;
        try{
           // gd.begin();
            //llistat= gd.Llista(Contenidor.class,ini,fi);
            llistat= (Iterator<Contenidor>) gd.Llista(Contenidor.class, ini, fi, "nom", Config.ORDRE).iterator();
        }catch (BuitException e){
            log.error("No s'ha pogut obtenir el llistat de contenidors .",e.getLocalizedMessage());
            throw e;
        }catch(HibernateException e){
            log.error("llistat amb errors d'hibernate 1 ({})  ",e.getLocalizedMessage());
            throw e;
        }
        finally{
           // gd.close();
        }
        return llistat;
    }

    public Iterator<Contenidor> llista(String ordre, int quants)  throws HibernateException, BuitException{
        Iterator<Contenidor> llistat =null;
        try{
         //   gd.begin();
            llistat= (Iterator<Contenidor>) gd.Llista(Contenidor.class,ordre,quants).iterator();
        }catch (BuitException e){
            log.error("No s'ha pogut obtenir el llistat de contenidors .{}",e.getLocalizedMessage());
            throw e;
        }catch(HibernateException e){
            log.error("llistat amb errors d'hibernate 2 ({})  ",e.getLocalizedMessage());
            throw e;
        }
        finally{
           // gd.close();
        }
        return llistat;
    }

    protected Iterator<Contenidor> llista(String camp, String cmp,Object nom,int ini, int fi)  throws HibernateException, BuitException{
        Iterator<Contenidor> llistat =null;
        try{
            llistat= (Iterator<Contenidor>) gd.Llista(Contenidor.class,camp,cmp,nom, ini, fi, camp, Config.ORDRE).iterator();
        }catch (BuitException e){
            log.error("No s'ha pogut obtenir el llistat de contenidors. {}",e.getLocalizedMessage());
            throw e;
        }catch(HibernateException e){
            log.error("llistat amb errors d'hibernate 1 ({})  ",e.getLocalizedMessage());
            throw e;
        }
        finally{
           // gd.close();
        }
        return llistat;
    }

    public int quantsContenidors()throws HibernateException, BuitException{
         Integer quants=Config.valorNullInt;

        try {
         //   gd.begin();
            quants=gd.quants( Contenidor.class);
        }catch (HibernateException e){
            log.error("Error en la connexió amb la bdd. No s'ha pogut obtenir el nombre de contenidors.",e.getLocalizedMessage());

        }catch (BuitException e){
            log.error("No hi ha contenidors.{}",e.getLocalizedMessage());

        }
        return quants;
    }
    /**
     * 
     * @param nomCercat
     * @return El nombre d'entitats que cumpleixen la condició
     * @throws HibernateException
     * @throws BuitException
     */
    public int quantsContenidors(String camp, String comparacio,String nomCercat)
            throws HibernateException, BuitException{
         Integer quants=Config.valorNullInt;

        try {
         //   gd.begin();
            quants=gd.quants( Contenidor.class,camp,comparacio,nomCercat);
        }catch (HibernateException e){
            log.error("Error en la connexió amb la bdd. No s'ha pogut obtenir el nombre de contenidors.",e.getLocalizedMessage());

        }catch (BuitException e){
            log.error("No hi ha contenidors.{}",e.getLocalizedMessage());

        }
        return quants;
    }
    

    /*****************************************************************
     *
     * TEST
     *
     */
    private void testLlistat(ContenidorsDAO cDao) {
         Iterator<Contenidor> it=null;
        try {
            it= cDao.llista("desc",7);
            Contenidor contenidor=null;
            Eines.escriu("Prova llistat Contenidors");
            Eines.escriu("=========================");
            while (it.hasNext()){
                contenidor=it.next();
                Eines.escriu("Dades ítem :"+contenidor.toString());
            }
        }catch(HibernateException e){
            log.error("Error hibernate llistat");
        }catch(BuitException e){
            log.error("Error Buit llistat");
        }
       
        Eines.escriu("");
    }
    private void testConsulta (ContenidorsDAO cDao) {
        Contenidor contenidor=null;
        try {
            contenidor=cDao.consultaContenidor(1L);

            Eines.escriu("Prova consulta contenidor");
            Eines.escriu("=========================");
        
            Eines.escriu("Contenidor :"+contenidor.toString());
        }catch(HibernateException e){
            log.error("Error hibernate consulta");
        }catch(BuitException e){
            log.error("Error Buit consulta");
        }
        Eines.escriu("");
    }
   
    private void testQuants(ContenidorsDAO cDao){
        Eines.escriu("Prova quants Contenidors");
        Eines.escriu("========================");
        try {
            Eines.escriu(cDao.quantsContenidors());
        } catch (HibernateException ex) {
            this.log.error("Error en la connexió a la bdd");
        } catch (BuitException ex) {
            this.log.error("No hi ha contenidors");
        }
        Eines.escriu("");
    }

    private void testEliminar(ContenidorsDAO cDao){

            Contenidor c=null;
        try {
            c = cDao.consultaContenidor(1L);
        } catch (HibernateException ex) {
            Logger.getLogger(ContenidorsDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (BuitException ex) {
            Logger.getLogger(ContenidorsDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
            Item it=(Item)c.getItems().get(20);
            Eines.escriu("Quants: "+c.getItems().size());
            c.getItems().remove(it);

        try {
            //GestorItems gi = new GestorItems();
            ItemsDAO iDao = new ItemsDAO();
            iDao.eliminarItem(it);
            //gi.eliminarItem(it);
            iDao.tancarConnexio();
        } catch (HibernateException ex) {
            Logger.getLogger(ContenidorsDAO.class.getName()).log(Level.SEVERE, null, ex);
        }catch (BuitException ex) {
            Logger.getLogger(ContenidorsDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
            Eines.escriu("Quants: "+c.getItems().size());
        try {
            //it=null;
            //c=null;
            cDao.modificarContenidor(c);
        } catch (HibernateException ex) {
            Logger.getLogger(ContenidorsDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (BuitException ex) {
            Logger.getLogger(ContenidorsDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
           // cDao.persist(c);
            //gc.persist(c);
            
    }

    public static void main(String args[]) {
        ContenidorsDAO cDao = new ContenidorsDAO();
        //cDao.testLlistat(cDao);
        //cDao.testConsulta(cDao);
        //cDao.testQuants(cDao);

        //cDao.testEliminar(cDao);
         Iterator<Contenidor> lc;
        try {
            lc = cDao.llista("nom", "=","con", 0, 37);
            while (lc.hasNext()){
            Contenidor c =lc.next();
            Eines.escriu(c.getNom());
        }


        } catch (HibernateException ex) {
            Logger.getLogger(ContenidorsDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (BuitException ex) {
            Logger.getLogger(ContenidorsDAO.class.getName()).log(Level.SEVERE, null, ex);
        }



        cDao.tancarConnexio();

    }
}
